home *** CD-ROM | disk | FTP | other *** search
/ Winzipper / Winzipper_ISO.iso / programming / oracle7 7.2 / OCI72 / CDEMO1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-15  |  11.4 KB  |  416 lines

  1. #ifdef RCSID
  2.    "$Header: cdemo1.c 7020100.1 94/09/23 22:19:32 cli Generic<base> $ ";
  3. #endif /* RCSID */
  4.  
  5. /* Copyright (c) 1991 by Oracle Corporation */
  6. /*
  7.    NAME
  8.      cdemo1.c - C Demo Program
  9.    MODIFIED   (MM/DD/YY)
  10.     emendez    06/28/94 -  fix ansi warnings
  11.     emendez    04/07/94 -  merge changes from branch 1.8.710.2
  12.     gdoherty   04/06/94 -  merge changes from branch 1.8.710.1
  13.     emendez    02/02/94 -  Fix for bug 157576
  14.     gdoherty   01/31/94 -  make oci header inclusion for ansi or k+r adaptive
  15.     tssmith    03/29/93 -  Changing to non-ANSI function defs and decls
  16.     lfeng      01/13/93 -  fix non-portable fflush 
  17.     rkooi2     11/27/92 -  Datatype changes to agree with ocidef.h 
  18.     lfeng      11/20/92 -  add more portability modes 
  19.     rkooi2     11/04/92 -  Fix comp errors 
  20.     rkooi2     10/27/92 -  More portability mods 
  21.     rkooi2     10/18/92 -  Changes to make it portable 
  22.     sjain      03/16/92 -  Creation 
  23. */
  24. /* 
  25.  *      -- cdemo1.c --
  26.  *  An example program which adds new employee
  27.  *  records to the personnel data base.  Checking
  28.  *  is done to insure the integrity of the data base.
  29.  *  The employee numbers are automatically selected using
  30.  *  the current maximum employee number as the start.
  31.  *  
  32.  *  The program queries the user for data as follows:
  33.  *   
  34.  *  Enter employee name:
  35.  *  Enter employee job:
  36.  *  Enter employee salary:
  37.  *  Enter employee dept:
  38.  *   
  39.  *  The program terminates if return key (CR) is entered
  40.  *  when the employee name is requested.
  41.  *   
  42.  *  If the record is successfully inserted, the following
  43.  *  is printed:
  44.  *   
  45.  *  "ename" added to department "dname" as employee # "empno"
  46.  */
  47.  
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52.  
  53.  
  54. #include <oratypes.h>
  55. /* LDA and CDA struct declarations */
  56. #include <ocidfn.h>
  57. #ifdef __STDC__
  58. #include <ociapr.h>
  59. #else
  60. #include <ocikpr.h>
  61. #endif
  62. /* demo constants and structs */
  63. #include <ocidem.h>
  64.  
  65. /* oparse flags */
  66. #define  DEFER_PARSE        1
  67. #define  NATIVE             1
  68. #define  VERSION_7          2
  69.  
  70. text *username = (text *) "SCOTT";
  71. text *password = (text *) "TIGER";
  72.  
  73. /* Define SQL statements to be used in program. */
  74. text *insert = (text *) "INSERT INTO emp(empno, ename, job, sal, deptno)\
  75.     VALUES (:empno, :ename, :job, :sal, :deptno)";
  76. text *seldept = (text *) "SELECT dname FROM dept WHERE deptno = :1";
  77. text *maxemp = (text *) "SELECT NVL(MAX(empno), 0) FROM emp";
  78. text *selemp = (text *) "SELECT ename, job FROM emp";
  79.  
  80. /* Define an LDA, a HDA,  and two cursors. */
  81. Lda_Def lda;
  82. ub1     hda[HDA_SIZE];
  83. Cda_Def cda1;
  84. Cda_Def cda2;
  85.  
  86.  
  87. void err_report();
  88. void do_exit(sword exit_code);
  89. void myfflush();
  90.  
  91.  
  92. void main()
  93. {
  94.     sword empno, sal, deptno;
  95.     sword len, len2, dsize, dsize2;
  96.     sb4   enamelen, joblen, deptlen;
  97.     sb2   sal_ind, job_ind;
  98.     sb2   db_type;
  99.     sb1   name_buf[20], name2_buf[20];
  100.     text  *cp, *ename, *job, *dept;
  101.  
  102. /* 
  103.  *  Connect to ORACLE and open two cursors.
  104.  *  Exit on any error.
  105.  */
  106.     if (orlon(&lda, hda, username, -1, password, -1, 0))
  107.     {
  108.         err_report(&lda);
  109.         exit(EXIT_FAILURE);
  110.     }
  111.     printf("Connected to ORACLE as %s\n", username);
  112.  
  113.     if (oopen(&cda1, &lda, (text *) 0, -1, -1, (text *) 0, -1))
  114.     {
  115.         err_report(&cda1);
  116.         do_exit(EXIT_FAILURE);
  117.     }
  118.     if (oopen(&cda2, &lda, (text *) 0, -1, -1, (text *) 0, -1))
  119.     {
  120.         err_report(&cda2);
  121.         do_exit(EXIT_FAILURE);
  122.     }
  123.  
  124.     /* Turn off auto-commit. Default is off, however. */
  125.     if (ocof(&lda))
  126.     {
  127.         err_report(&lda);
  128.         do_exit(EXIT_FAILURE);
  129.     }
  130.  
  131.     /* Retrieve the current maximum employee number. */
  132.     if (oparse(&cda1, maxemp, (sb4) -1, DEFER_PARSE,
  133.                (ub4) VERSION_7))
  134.     {
  135.         err_report(&cda1);
  136.         do_exit(EXIT_FAILURE);
  137.     }
  138.     if (odefin(&cda1, 1, (ub1 *) &empno, (sword) sizeof(sword),
  139.                (sword) INT_TYPE,
  140.                (sword) -1, (sb2 *) 0, (text *) 0, -1, -1,
  141.                (ub2 *) 0, (ub2 *) 0))
  142.     {
  143.         err_report(&cda1);
  144.         do_exit(EXIT_FAILURE);
  145.     }
  146.     if (oexfet(&cda1, (ub4) 1, FALSE, FALSE))
  147.     {
  148.         if (cda1.rc == NO_DATA_FOUND)
  149.             empno = 10;
  150.         else
  151.         {
  152.             err_report(&cda1);
  153.             do_exit(EXIT_FAILURE);
  154.         }
  155.     }
  156.  
  157.     /*  Describe the columns in the select-list
  158.         of "selemp" to determine the max length of
  159.         the employee name and job title.
  160.      */
  161.     if (oparse(&cda1, selemp, (sb4) -1, FALSE, VERSION_7))
  162.     {
  163.         err_report(&cda1);
  164.         do_exit(EXIT_FAILURE);
  165.     }
  166.  
  167.     len = sizeof(name_buf); len2 = sizeof (name2_buf);
  168.     if (odescr(&cda1, 1, &enamelen,
  169.                (sb2 *) &db_type, name_buf, (sb4 *) &len,
  170.                (sb4 *) &dsize, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0) ||
  171.         odescr(&cda1, 2, &joblen,
  172.                (sb2 *) &db_type, name2_buf, (sb4 *) &len2,
  173.                (sb4 *) &dsize2, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0))
  174.     {
  175.         err_report(&cda1);
  176.         do_exit(EXIT_FAILURE);
  177.     }
  178.  
  179.     /* Parse the INSERT statement. */
  180.     if (oparse(&cda1, insert, (sb4) -1, FALSE, (ub4) VERSION_7))
  181.     {
  182.         err_report(&cda1);
  183.         do_exit(EXIT_FAILURE);
  184.     }
  185.  
  186.     /* Parse the SELDEPT statement. */
  187.     if (oparse(&cda2, seldept, (sb4) -1, FALSE, (ub4) VERSION_7))
  188.     {
  189.         err_report(&cda2);
  190.         do_exit(EXIT_FAILURE);
  191.     }
  192.  
  193.     /*  Allocate output buffers. Allow for \n and '\0'. */
  194.     ename = (text *) malloc((int) enamelen + 2);
  195.     job   = (text *) malloc((int) joblen + 2);
  196.  
  197.     /*  Bind the placeholders in the INSERT statement. */
  198.     if (obndrv(&cda1, (text *) ":ENAME", -1, (ub1 *) ename,
  199.                enamelen+1, STRING_TYPE, -1, (sb2 *) 0,
  200.                (text *) 0, -1, -1) ||
  201.         obndrv(&cda1, (text *) ":JOB", -1, (ub1 *) job, joblen+1,
  202.                STRING_TYPE, -1, &job_ind, (text *) 0, -1, -1) ||
  203.         obndrv(&cda1, (text *) ":SAL", -1, (ub1 *) &sal, (sword) sizeof (sal),
  204.                INT_TYPE, -1, &sal_ind, (text *) 0, -1, -1) ||
  205.         obndrv(&cda1, (text *) ":DEPTNO",-1, (ub1 *) &deptno,
  206.                (sword) sizeof (deptno), INT_TYPE, -1,
  207.                (sb2 *) 0, (text *) 0, -1, -1) ||
  208.         obndrv(&cda1, (text *) ":EMPNO", -1, (ub1 *) &empno,
  209.                (sword) sizeof (empno), INT_TYPE, -1,
  210.                (sb2 *) 0, (text *) 0, -1, -1))
  211.     {
  212.         err_report(&cda1);
  213.         do_exit(EXIT_FAILURE);
  214.     }
  215.  
  216.     /*  Bind the placeholder in the "seldept" statement. */
  217.     if (obndrn(&cda2,
  218.                1,
  219.                (ub1 *) &deptno,
  220.                (sword) sizeof(deptno),
  221.                INT_TYPE,
  222.                -1,
  223.                (sb2 *) 0,
  224.                (text *) 0,
  225.                -1,
  226.                -1))
  227.     {
  228.         err_report(&cda2);
  229.         do_exit(EXIT_FAILURE);
  230.     }  
  231.  
  232.     /*  Describe the select-list field "dname". */
  233.     len = sizeof (name_buf);
  234.     if (odescr(&cda2, 1, (sb4 *) &deptlen, &db_type,
  235.                name_buf, (sb4 *) &len, (sb4 *) &dsize, (sb2 *) 0,
  236.                (sb2 *) 0, (sb2 *) 0))
  237.     {
  238.         err_report(&cda2);
  239.         do_exit(EXIT_FAILURE);
  240.     }
  241.  
  242. /*  Allocate the dept buffer now that you have length. */
  243.     dept = (text *) malloc((int) deptlen + 1);
  244.  
  245.     /*  Define the output variable for the select-list. */
  246.     if (odefin(&cda2,
  247.                1,
  248.                (ub1 *) dept,
  249.                deptlen+1,
  250.                STRING_TYPE,
  251.                -1,
  252.                (sb2 *) 0,
  253.                (text *) 0,
  254.                -1,
  255.                -1,
  256.                (ub2 *) 0,
  257.                (ub2 *) 0))
  258.     {
  259.         err_report(&cda2);
  260.         do_exit(EXIT_FAILURE);
  261.     }
  262.  
  263.     for (;;)
  264.     {
  265.         /* Prompt for employee name.  Break on no name. */
  266.         printf("\nEnter employee name (or CR to EXIT): ");
  267.         fgets((char *) ename, (int) enamelen+1, stdin);
  268.         cp = (text *) strchr((char *) ename, '\n');
  269.         if (cp == ename)
  270.         {
  271.             printf("Exiting... ");
  272.             do_exit(EXIT_SUCCESS);
  273.         }
  274.         if (cp)
  275.             *cp = '\0';
  276.         else
  277.       {
  278.             printf("Employee name may be truncated.\n");
  279.         myfflush();
  280.       }
  281.         /*  Prompt for the employee's job and salary. */
  282.         printf("Enter employee job: ");
  283.         job_ind = 0;
  284.         fgets((char *) job, (int) joblen + 1, stdin);
  285.         cp = (text *) strchr((char *) job, '\n');
  286.         if (cp == job)
  287.         {
  288.             job_ind = -1;            /* make it NULL in table */
  289.             printf("Job is NULL.\n");/* using indicator variable */
  290.         }
  291.         else if (cp == 0)
  292.       {
  293.             printf("Job description may be truncated.\n");
  294.         myfflush();
  295.       }
  296.         else
  297.             *cp = '\0';
  298.  
  299.         printf("Enter employee salary: ");
  300.         scanf("%d", &sal);
  301.     myfflush();
  302.         sal_ind = (sal <= 0) ? -2 : 0;  /* set indicator variable */
  303.  
  304.         /*
  305.          *  Prompt for the employee's department number, and verify
  306.          *  that the entered department number is valid
  307.          *  by executing and fetching.
  308.          */
  309.         do
  310.         {
  311.             printf("Enter employee dept: ");
  312.             scanf("%d", &deptno);
  313.         myfflush();
  314.             if (oexec(&cda2) ||
  315.                     (ofetch(&cda2) && (cda2.rc != NO_DATA_FOUND)))
  316.             {
  317.                 err_report(&cda2);
  318.                 do_exit(EXIT_FAILURE);
  319.             }  
  320.             if (cda2.rc == NO_DATA_FOUND)
  321.                 printf("The dept you entered doesn't exist.\n");
  322.         } while (cda2.rc == NO_DATA_FOUND);
  323.  
  324.         /*
  325.          *  Increment empno by 10, and execute the INSERT
  326.          *  statement. If the return code is 1 (duplicate
  327.          *  value in index), then generate the next
  328.          *  employee number.
  329.          */
  330.         empno += 10;
  331.         if (oexec(&cda1) && cda1.rc != 1)
  332.         {
  333.             err_report(&cda1);
  334.             do_exit(EXIT_FAILURE);
  335.         }
  336.         while (cda1.rc == 1)
  337.         {
  338.             empno += 10;
  339.             if (oexec(&cda1) && cda1.rc != 1)
  340.             {
  341.                 err_report(&cda1);
  342.                 do_exit(EXIT_FAILURE);
  343.             }
  344.         }  /* end for (;;) */
  345.  
  346. /* Commit the change. */
  347.         if (ocom(&lda))
  348.         {
  349.             err_report(&lda);
  350.             do_exit(EXIT_FAILURE);
  351.         }
  352.         printf(
  353.         "\n\n%s added to the %s department as employee number %d\n",
  354.                  ename, dept, empno);
  355.     }
  356.     do_exit(EXIT_SUCCESS);
  357.  
  358. }
  359.  
  360.  
  361. void
  362. err_report(cursor)
  363.     Cda_Def *cursor;
  364. {
  365.     sword n;
  366.     text msg[512];
  367.  
  368.     printf("\n-- ORACLE error--\n");
  369.     printf("\n");
  370.     n = oerhms(&lda, cursor->rc, msg, (sword) sizeof msg);
  371.     fprintf(stderr, "%s\n", msg);
  372.     if (cursor->fc > 0)
  373.         fprintf(stderr, "Processing OCI function %s",
  374.             oci_func_tab[cursor->fc]);
  375. }
  376.  
  377.  
  378. /*
  379.  *  Exit program with an exit code.
  380.  */
  381. void do_exit(exit_code)
  382.     sword exit_code;
  383. {
  384.     sword error = 0;
  385.  
  386.     if (oclose(&cda1))
  387.     {
  388.         fprintf(stderr, "Error closing cursor 1.\n");
  389.         error++;
  390.     }
  391.     if (oclose(&cda2))
  392.     {
  393.         fprintf(stderr, "Error closing cursor 2.\n");
  394.         error++;
  395.     }
  396.     if (ologof(&lda))
  397.     {
  398.         fprintf(stderr, "Error on disconnect.\n");
  399.         error++;
  400.     }
  401.     if (error == 0 && exit_code == EXIT_SUCCESS)
  402.         printf ("\nG'day\n");
  403.  
  404.     exit(exit_code);
  405. }
  406.  
  407.  
  408. void myfflush()
  409. {
  410.   eb1 buf[50];
  411.  
  412.   fgets((char *) buf, 50, stdin);
  413. }
  414.  
  415.  
  416.